package com.telnetnz.ticketdesk.action.ticketcomment;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.rockbb.common.simpleframe.action.MultipartFile;
import com.rockbb.common.simpleframe.config.SimpleConfig;
import com.rockbb.common.utilities.security.StringDigest;
import com.rockbb.common.utilities.time.TimeUtil;
import com.telnetnz.ticketdesk.action.base.BasicSessionPageAccAction;
import com.telnetnz.ticketdesk.action.common.CommonUtils;
import com.telnetnz.ticketdesk.bean.Attachment;
import com.telnetnz.ticketdesk.bean.Ticket;
import com.telnetnz.ticketdesk.bean.TicketComment;
import com.telnetnz.ticketdesk.service.AttachmentService;
import com.telnetnz.ticketdesk.service.OperationLogService;
import com.telnetnz.ticketdesk.service.TicketCommentService;
import com.telnetnz.ticketdesk.service.TicketService;

public class TicketCommentEditAction extends BasicSessionPageAccAction
{
	private static Logger logger = Logger.getLogger(TicketCommentEditAction.class);

	public String doEdit()
	{
		TicketEditBean bean = new TicketEditBean();
		if (bean.getComment() == null)
			return this.message_box(
					langRes.get("global.operation-fail"),
					langRes.get("comment.comment-not-exist-redirect", new String[]{bean.getRedirect()}),
					bean.getRedirect(),
					2);
		else if (!isSuperSession() && !bean.getComment().isEditable(getSession().getSession_uuid()))
			return this.message_box(
					langRes.get("global.no-permission"),
					langRes.get("global.no-permission-redirect", new String[]{bean.getRedirect()}),
					bean.getRedirect(),
					2);

		if (bean.isSubmitted())
		{
			if (bean.getAddAttachment().length() > 0 || bean.getDeleteAttachmentId() > 0L)
			{
				// Go back to INPUT
			}
			else
			{
				if (bean.validate())
				{
					String message;
					if(bean.getComment().getId() == 0)
					{
						bean.getComment().setCreatorId(getSession().getSession_uuid());
						bean.getComment().setUpdaterId(getSession().getSession_uuid());
						TicketCommentService.add(bean.getComment());

						OperationLogService.addLog(
								OperationLogService.OBJECT_TYPE_TICKETCOMMENT,
								bean.getComment().getId(),
								getSession().getSession_uuid(),
								getContext().getActionName(),
								null);

						TicketCommentService.sendNotification(bean.getComment(), 0);
						message = langRes.get("comment.comment-add-success-redirect", new String[]{bean.getRedirect()});
					}
					else
					{
						Map<String, List<String>> diff = bean.getComment().compare();
						bean.getComment().setUpdaterId(getSession().getSession_uuid());
						TicketCommentService.update(bean.getComment());

						OperationLogService.addLog(
								OperationLogService.OBJECT_TYPE_TICKETCOMMENT,
								bean.getComment().getId(),
								getSession().getSession_uuid(),
								getContext().getActionName(),
								diff);

						message = langRes.get("comment.comment-update-success-redirect", new String[]{bean.getRedirect()});
					}

					for (Attachment attachment: bean.getAttachments())
					{
						Attachment dummy = AttachmentService.getAttachment(attachment.getId());
						if (dummy.getCommentId() == 0L)
						{
							dummy.setCommentId(bean.getComment().getId());
							AttachmentService.update(dummy);
						}
					}

					return this.message_box(
							langRes.get("global.operation-success"), 
							message,
							bean.getRedirect(),
							2
						);
				}
			}
		}

		this.put_page_key("bean", bean);

		this.put_page_key("post_action", baseLink());
		this.put_js_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.min.js",
				SimpleConfig.getConfig("static_file_url")+"/js/tiny_mce/tiny_mce.js"});

		this.put_css_key("source_files", new String[] {
				SimpleConfig.getConfig("static_file_url")+"/js/jquery-ui.css"});

		return INPUT;
	}

	public class TicketEditBean extends FileRequestBean
	{
		private TicketComment comment;
		private List<Attachment> attachments;
		private String addAttachment;
		private long deleteAttachmentId;

		public TicketComment getComment() {
			return comment;
		}

		public String getAddAttachment() {
			return addAttachment;
		}

		public long getDeleteAttachmentId() {
			return deleteAttachmentId;
		}

		public List<Attachment> getAttachments() {
			return attachments;
		}

		@Override
		protected void loadRequest() 
		{
			long id = getLong("id", 0L);
			if (id > 0)
			{
				comment = TicketCommentService.getRawTicketComment(id);
			}
			else
			{
				long ticketId = getLong("ticket_id", 0L);
				Ticket ticket = TicketService.getTicket(ticketId);
				if (ticket != null)
				{
					comment = new TicketComment();
					comment.initialize();
					comment.setTicketId(ticketId);
				}
			}

			if (comment != null)
			{
				if (isSubmitted())
				{
					comment.setContent(get("comment_content"));

					// Attachments
					long[] array2 = getLongArray("attachments", new long[]{}, null);
					attachments = new ArrayList<Attachment>();
					if (array2 != null && array2.length > 0)
					{
						for (long attId: array2)
						{
							Attachment att = AttachmentService.getAttachment(attId);
							if (att != null)
							{
								attachments.add(att);
							}
						}
					}

					// Delete attachment
					deleteAttachmentId = getLong("delete_attachment_id", 0L);
					if (deleteAttachmentId > 0L)
					{
						for (int i = 0; i < attachments.size(); i ++)
						{
							if (attachments.get(i).getId() == deleteAttachmentId)
							{
								AttachmentService.deleteByPrimaryKey(deleteAttachmentId);
								attachments.remove(i);
								break;
							}
						}
					}

					// New attachment
					addAttachment = get("add_attachment");

					// Add new attachment in spite of "att_attachment", because sometimes it is submitted by the Submit button
					MultipartFile multipartFile = getFile("fileupload");
					if(multipartFile != null && multipartFile.getSize() > 0 && attachmentValidate(multipartFile))
					{
						Attachment attachment = new Attachment();
						attachment.initialize();
						attachment.setCommentId(comment.getId());
						attachment.setCreatorId(getSession().getSession_uuid());
						attachment.setSize(multipartFile.getSize());
						attachment.setName(multipartFile.getOriginalFilename());

						// Guess the mime-type
						String mimeType = multipartFile.getContentType();
						if (mimeType.equals("application/octet-stream"))
						{
							mimeType = getRequest().getSession().getServletContext().getMimeType(multipartFile.getOriginalFilename());
						}
						if (mimeType == null)
						{
							mimeType = "application/octet-stream";
						}
						attachment.setMimeType(mimeType);

						int fileType = AttachmentService.getFileType(mimeType);
						attachment.setType(fileType);

						String targetFolder = TimeUtil.getStr(new Date(), "yyyy/MM/");
						String targetName = TimeUtil.getStr(new Date(), "yyyyMMddHHmm") + "_" + StringDigest.unique_id().substring(24);
						String extension = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf('.'));
						String targetFullPath = 
								SimpleConfig.getConfig("file_physical_path")  
								+ SimpleConfig.getConfig("file_for_static") 
								+ targetFolder + targetName + extension;

						// Move it to the target folder
						if (CommonUtils.uploadFile(multipartFile, targetFullPath))
						{
							attachment.setPath(targetFolder + targetName + extension);
							AttachmentService.add(attachment);
							attachments.add(attachment);
						}
						else
							logger.error("IOException: can not move file to " + targetFullPath);
					}

					// attachment end
				}
				else
				{
					if (id > 0L)
					{
						attachments = AttachmentService.getAttachmentsByPageAndCondition(
								0, 
								10, 
								AttachmentService.ORDERBY_CREATE_TIME, 
								0, 
								-1L, 
								comment.getId(),
								0L);
					}
					else
					{
						// When adding new comment, load only the attachments created by the user self
						attachments = AttachmentService.getAttachmentsByPageAndCondition(
								0, 
								10, 
								AttachmentService.ORDERBY_CREATE_TIME, 
								0, 
								0L, 
								0L,
								getSession().getSession_uuid());
					}
				}
			}
		}

		private boolean attachmentValidate(MultipartFile multipartFile)
		{
			boolean flag = true;

			long maxSize = AttachmentService.SIZE_LIMIT;
			if (multipartFile.getSize() >= maxSize)
			{
				flag = false;
				this.put_error_msg("fileupload", langRes.get("attachment.file-size-exceed-limit"));
			}
			return flag;
		}

		@Override
		protected boolean validate() 
		{
			boolean flag = true;

			if (comment.getContent().length() == 0)
			{
				flag = false;
				put_error_msg("comment_content", langRes.get("global.content-cannot-be-empty"));
			}

			return flag;
		}
	}
}
